/*
 * Copyright (c) 2024 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

/**
 * @file default_supervisor.h
 * @brief 默认监督器实现
 */
#ifndef MC_CORE_DEFAULT_SUPERVISOR_H
#define MC_CORE_DEFAULT_SUPERVISOR_H

#include "dependency_sorter.h"

#include <mc/core/service.h>
#include <mc/core/supervisor.h>

namespace mc::core {

using dependency_node = mc::core::internal::dependency_sorter::dependency_node;

/**
 * @brief 默认监督器实现
 *
 * 负责管理服务的生命周期，包括启动、停止、重启和健康检查
 */
class default_supervisor : public supervisor,
                           public std::enable_shared_from_this<default_supervisor> {
public:
    default_supervisor();
    ~default_supervisor() override = default;

    bool init(const config::supervisor_config& config) override;
    bool start() override;
    bool stop() override;
    void cleanup() override;

    bool             add_service(service_base_ptr service) override;
    bool             remove_service(const std::string& name) override;
    service_base_ptr get_service(const std::string& name) const override;

    bool           add_child(supervisor_ptr child) override;
    bool           remove_child(const std::string& name) override;
    supervisor_ptr get_child(const std::string& name) const override;

    const config::supervisor_config& get_config() const override {
        return m_config;
    }
    bool is_healthy() const override;

    const std::string& name() const override {
        return m_name;
    }

    std::vector<std::string> get_service_stop_order() const;

protected:
    bool        restart_all_services() override;
    bool        restart_dependent_services(const std::string& service_name) override;
    bool        restart_one_service(const std::string& name);
    void        handle_service_crash(const std::string& name);
    std::string get_strategy_name(config::supervisor_strategy strategy);

private:
    config::supervisor_config   m_config;       // 监督器配置
    std::string                 m_name;         // 监督器名称
    config::supervisor_strategy m_strategy;     // 监督策略
    int                         m_max_restarts; // 最大重启次数

    mutable std::mutex m_mutex;
    std::atomic<bool>  m_started;

    // 服务映射表 (name -> service)
    std::unordered_map<std::string, service_base_ptr> m_services;

    // 子监督器映射表 (name -> supervisor)
    std::unordered_map<std::string, supervisor_ptr> m_child_supervisors;

    // 重启信息
    struct restart_info {
        int                                   restart_count = 0;
        std::chrono::steady_clock::time_point last_restart;
    };

    std::unordered_map<std::string, restart_info> m_restart_infos;
    int                                           m_restart_count = 0;
    std::chrono::steady_clock::time_point         m_last_restart_time;

    // 获取服务停止顺序
    std::vector<std::string> get_service_stop_order_internal() const;

    // 获取服务停止顺序
    std::vector<std::string> get_service_stop_order(bool already_locked = false) const;

    // 搜集依赖服务
    void collect_dependent_services(const std::unordered_map<std::string, dependency_node>& graph,
                                    const std::string&                                      service_name,
                                    std::unordered_set<std::string>&                        affected_services);

    // 启动单个服务
    bool start_one_service(const std::string& name);

    // 停止单个服务
    bool stop_one_service(const std::string& name);

    // 停止单个子监督器
    bool stop_one_child_supervisor(const std::string& name);
};

} // namespace mc::core

#endif // MC_CORE_DEFAULT_SUPERVISOR_H